home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS13.ADF
/
FutureSound
/
playsound.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-08-05
|
4KB
|
227 lines
/* PlaySound.c */
/* This routine sets up an ioRequest and plays back a */
/* waveform through the Amiga audio hardware */
/* Usage : PlaySound(buffer,repeat,period,volume) */
/* buffer is a pointer to a waveform */
/* repeat is the number of times to play the wave (0 == forever) */
/* period determines the playback rate (minimum value == 124) */
/* volume goes from 0 to 64 */
#include "exec/types.h"
#include "devices/audio.h"
#include "exec/memory.h"
#include "SoundErrors.h"
#define LEFT0F 1
#define RIGHT0F 2
#define RIGHT1F 4
#define LEFT1F 8
extern struct MsgPort *CreatePort();
/* Look for a left channel, then a right */
UBYTE allocationMap[] = {LEFT0F,LEFT1F,RIGHT0F,RIGHT1F};
/* Allocate and initialize an IO Request Block */
SetIOA(per,vol,repeat,len,ioa)
int per,vol,repeat;
ULONG len;
struct IOAudio **ioa;
{
struct MsgPort *port;
char *PortName;
PortName = "Sound Channel";
/* Allocate IOAudio structure */
(*ioa) = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),
MEMF_PUBLIC|MEMF_CLEAR);
/* If Allocation Successful ... */
if((*ioa)!=0)
{
/* Set Priority */
(*ioa)->ioa_Request.io_Message.mn_Node.ln_Pri = 10;
/* Create Message port for IORequest to talk to Amiga */
if ((port = CreatePort(PortName,0)) == 0)
{
FreeMem((*ioa),sizeof(struct IOAudio));
}
/* If Creation Successful ... */
else
{
/* Get a channel */
(*ioa)->ioa_Request.io_Message.mn_ReplyPort = port;
(*ioa)->ioa_Data = allocationMap;
(*ioa)->ioa_Length = sizeof(allocationMap);
/* Open Audio Device for output */
if(OpenDevice(AUDIONAME,0,(*ioa),0) != 0)
{
DeletePort(port);
FreeMem((*ioa),sizeof(struct IOAudio));
}
/* If open worked ... */
else
{
/* Set Up Request */
(*ioa)->ioa_Request.io_Flags = ADIOF_PERVOL;
(*ioa)->ioa_Request.io_Command = CMD_WRITE;
(*ioa)->ioa_Period = per;
(*ioa)->ioa_Volume = vol;
/* For some reason, the Audio chip can't play samples */
/* longer than 131k, so we kludge. Oh, well. */
if(len<131000)
{
(*ioa)->ioa_Cycles = repeat;
}
else
{
(*ioa)->ioa_Cycles = 1;
}
}
}
}
}
/* Play a sound */
struct IOAudio *PlaySound(buffer,buflen,repeat,period,volume)
BYTE *buffer;
ULONG buflen;
int repeat,period,volume;
{
struct IOAudio *ioa;
BYTE *DataPtr;
ULONG PlayLen=0;
int sound_done=0;
int count;
count = repeat?(repeat-1):-1;
DataPtr = buffer;
/* Set Up IOAudio structure */
SetIOA(period,volume,repeat,buflen,&ioa);
/* Set up data and length pointers of ioa */
SetLength(&PlayLen,buflen,&DataPtr,ioa);
/* Send command to Audio chip */
BeginIO(ioa);
/* If no data remains to play, return ioa pointer */
if(PlayLen == 0)
{
return(ioa);
}
/* If there is more (buflen >131000), continue until there isn't */
while(!sound_done)
{
/* If current chunk is done ... */
if(CheckIO(ioa))
{
/* If more remains, continue */
if(PlayLen > 0)
{
/* update pointers and start next chunk */
FixLength(&PlayLen,&DataPtr,ioa);
BeginIO(ioa);
if((PlayLen == 0) && (count == 0))
{
return(ioa);
}
}
/* If not ... */
else
{
/* Check repeat counter */
if(count != 0)
{
/* Restart wave */
DataPtr = buffer;
SetLength(&PlayLen,buflen,&DataPtr,ioa);
BeginIO(ioa);
if(count>0)
{
count--;
}
}
else
{
/* finished */
sound_done = 1;
}
}
}
}
/* Free IOAudio stuff */
StopSound(ioa);
}
StopSound(ioa)
struct IOAudio *ioa;
{
AbortIO(ioa);
if(ioa->ioa_Request.io_Device)
{
CloseDevice(ioa);
}
if(ioa->ioa_Request.io_Message.mn_ReplyPort)
{
DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
}
if(ioa)
{
FreeMem(ioa,sizeof(struct IOAudio));
}
}
SetLength(LenPtr,buflen,DataHndl,ioa)
ULONG *LenPtr,buflen;
BYTE **DataHndl;
struct IOAudio *ioa;
{
if(buflen<= 131000)
{
(*LenPtr) = buflen;
}
else
{
(*LenPtr) = 131000;
}
ioa->ioa_Length = (*LenPtr);
ioa->ioa_Data = (*DataHndl);
if((*LenPtr) != buflen)
{
(*LenPtr) = buflen - 131000;
(*DataHndl) += 131000;
}
else
{
(*LenPtr) = 0;
}
}
FixLength(LenPtr,DataHndl,ioa)
ULONG *LenPtr;
BYTE **DataHndl;
struct IOAudio *ioa;
{
if((*LenPtr) > 131000)
{
ioa->ioa_Length = 131000;
ioa->ioa_Data = (*DataHndl);
(*LenPtr) -= 131000;
(*DataHndl) += 131000;
}
else
{
ioa->ioa_Length = (*LenPtr);
ioa->ioa_Data = (*DataHndl);
(*LenPtr) = 0;
}
}